/*
 * Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package org.geometerplus.android.fbreader.network;

import java.util.*;

import android.app.AlertDialog;
import android.content.Intent;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;

//import net.youmi.android.AdManager;
//import net.youmi.android.AdView;

import org.geometerplus.zlibrary.core.network.ZLNetworkManager;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.util.ZLBoolean3;

import org.zixuanstudio.ebook.R;
import org.geometerplus.zlibrary.ui.android.network.SQLiteCookieDatabase;

import org.geometerplus.fbreader.tree.FBTree;
import org.geometerplus.fbreader.network.*;
import org.geometerplus.fbreader.network.tree.*;

import org.geometerplus.android.fbreader.BookShelf;
import org.geometerplus.android.fbreader.tree.TreeActivity;
import org.geometerplus.android.fbreader.network.action.*;

import org.geometerplus.android.util.Constant;
import org.geometerplus.android.util.UIUtil;

//import com.uucun.adsdk.UUAppConnect;
//import com.uucun.adsdk.UpdatePointListener;

public class NetworkLibraryActivity extends TreeActivity implements
		NetworkLibrary.ChangeListener, OnClickListener {
	static final String OPEN_CATALOG_ACTION = "android.fbreader.action.OPEN_NETWORK_CATALOG";

	protected static final int BASIC_AUTHENTICATION_CODE = 1;

	BookDownloaderServiceConnection Connection;

	final List<Action> myOptionsMenuActions = new ArrayList<Action>();
	final List<Action> myContextMenuActions = new ArrayList<Action>();
	final List<Action> myListClickActions = new ArrayList<Action>();
	private Intent myDeferredIntent;
	private boolean mySingleCatalog;

	private ImageButton homeImageButton;
	private ImageButton cateImageButton;
	private ImageButton topImageButton;
	private ImageButton fovImageButton;
	private ImageButton searchImageButton;

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		//UUAppConnect.getInstance(this).initSdk();
		// 应用Id 应用密码 广告请求间隔(s) 测试模式
		//AdManager.init(this,"480655328b365dc3", "a32e02720befac54 ", 30,
		// false);
		// LinearLayout v = (LinearLayout) LayoutInflater.from(this).inflate(
		// R.layout.net_book_store, null);
		// v.addView(new AdView(this), new
		// LayoutParams(LayoutParams.FILL_PARENT,
		// / LayoutParams.WRAP_CONTENT));
		setContentView(R.layout.net_book_store);
		SQLiteCookieDatabase.init(this);
		if (SQLiteNetworkDatabase.Instance() == null) {
			new SQLiteNetworkDatabase();
		}
		// AdView adView = new AdView(this);
		// FrameLayout.LayoutParams params = new
		// FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
		// FrameLayout.LayoutParams.WRAP_CONTENT);
		// 设置广告出现的位置(悬浮于屏幕右下角)
		// params.gravity=Gravity.BOTTOM|Gravity.RIGHT;
		// 将广告视图加入Activity中
		// addContentView(adView, params);

		//LinearLayout container =(LinearLayout)findViewById(R.id.ad_layout);
	   // UUAppConnect.getInstance(this).showBanner(container , 20);
		/*Button getPoints = (Button) findViewById(R.id.ad_layout);
		getPoints.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				UUAppConnect.getInstance(NetworkLibraryActivity.this).showOffers();				
			}
		});*/
		// UUAppConnect.getInstance(this).showOffers();
		
		LinearLayout container =(LinearLayout)findViewById(R.id.AdLinearLayout);
		SharedPreferences preference = this.getSharedPreferences(
				Constant.REAER_PREFERENCE_NAME, this.MODE_PRIVATE);
		boolean isInit = preference.getBoolean(Constant.INIT_NETBOOK, false);
		if (!isInit) {
			Log.v("fan", "loadDefault opds");
			SQLiteNetworkDatabase.Instance().loadDefaultOPDS();
			SharedPreferences.Editor editor = preference.edit();
			editor.putBoolean(Constant.INIT_NETBOOK, true);
			editor.commit();
		}

		Connection = new BookDownloaderServiceConnection();
		bindService(new Intent(getApplicationContext(),
				BookDownloaderService.class), Connection, BIND_AUTO_CREATE);
		setListAdapter(new NetworkLibraryAdapter(this));
		final Intent intent = getIntent();
		init(intent);
		myDeferredIntent = null;

		setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);

		if (getCurrentTree() instanceof RootTree) {
			mySingleCatalog = intent.getBooleanExtra("SingleCatalog", false);
			if (!NetworkLibrary.Instance().isInitialized()) {

				Util.initLibrary(this);
				myDeferredIntent = intent;
			} else {
				NetworkLibrary.Instance().fireModelChangedEvent(
						NetworkLibrary.ChangeListener.Code.SomeCode);
				openTreeByIntent(intent);
				if (getCurrentTree() instanceof NetworkCatalogTree) {
					final NetworkCatalogTree tree = (NetworkCatalogTree) getCurrentTree();
					Log.v("fan",
							"NetworkLibraryActivity.run.tree:" + tree.getName());
					checkAndRun(new ReloadCatalogAction(this), tree);
				}

			}
		}
	}

	@Override
	protected NetworkTree getTreeByKey(FBTree.Key key) {
		final NetworkLibrary library = NetworkLibrary.Instance();
		final NetworkTree tree = library.getTreeByKey(key);
		return tree != null ? tree : library.getRootTree();
	}

	@Override
	protected void onStart() {
		super.onStart();

		NetworkLibrary.Instance().addChangeListener(this);
	}

	@Override
	public void onResume() {
		super.onResume();
		getListView().setOnCreateContextMenuListener(this);
		NetworkLibrary.Instance().fireModelChangedEvent(
				NetworkLibrary.ChangeListener.Code.SomeCode);
		ZLNetworkManager.Instance().setCredentialsCreator(myCredentialsCreator);
	}

	@Override
	protected void onStop() {

		NetworkLibrary.Instance().removeChangeListener(this);
		super.onStop();
	}

	@Override
	public void onDestroy() {
		if (Connection != null) {
			unbindService(Connection);
			Connection = null;
		}
		//UUAppConnect.getInstance(this).exitSdk();
		super.onDestroy();
	}

	private boolean openTreeByIntent(Intent intent) {
		if (OPEN_CATALOG_ACTION.equals(intent.getAction())) {
			final Uri uri = intent.getData();
			if (uri != null) {
				final NetworkTree tree = NetworkLibrary.Instance()
						.getCatalogTreeByUrl(uri.toString());
				if (tree != null) {
					checkAndRun(new OpenCatalogAction(this), tree);
					return true;
				}
			}
		}
		return false;
	}

	@Override
	protected void onNewIntent(Intent intent) {
		if (!openTreeByIntent(intent)) {
			super.onNewIntent(intent);
		}
	}

	@Override
	public boolean onSearchRequested() {
		final NetworkTree tree = (NetworkTree) getCurrentTree();
		final RunSearchAction action = new RunSearchAction(this, false);
		if (action.isVisible(tree) && action.isEnabled(tree)) {
			action.run(tree);
			return true;
		} else {
			return false;
		}
	}

	@Override
	public boolean isTreeSelected(FBTree tree) {
		return false;
	}

	@Override
	protected boolean isTreeInvisible(FBTree tree) {
		return tree instanceof RootTree
				&& (mySingleCatalog || ((RootTree) tree).IsFake);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			final NetworkItemsLoader loader = NetworkLibrary.Instance()
					.getStoredLoader((NetworkTree) getCurrentTree());
			if (loader != null) {
				loader.interrupt();
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	private void fillOptionsMenuList() {
		myOptionsMenuActions.add(new RunSearchAction(this, false));
		myOptionsMenuActions.add(new AddCustomCatalogAction(this));
		myOptionsMenuActions.add(new RefreshRootCatalogAction(this));
		myOptionsMenuActions.add(new LanguageFilterAction(this));
		myOptionsMenuActions.add(new ReloadCatalogAction(this));
		myOptionsMenuActions.add(new SignInAction(this));
		myOptionsMenuActions.add(new SignUpAction(this));
		myOptionsMenuActions.add(new SignOutAction(this));
		myOptionsMenuActions.add(new TopupAction(this));
		myOptionsMenuActions.add(new BuyBasketBooksAction(this));
		myOptionsMenuActions.add(new ClearBasketAction(this));
	}

	private void fillContextMenuList() {
		myContextMenuActions.add(new OpenCatalogAction(this));
		myContextMenuActions.add(new OpenInBrowserAction(this));
		myContextMenuActions.add(new RunSearchAction(this, true));
		myContextMenuActions.add(new AddCustomCatalogAction(this));
		myContextMenuActions.add(new SignOutAction(this));
		myContextMenuActions.add(new TopupAction(this));
		myContextMenuActions.add(new SignInAction(this));
		myContextMenuActions.add(new EditCustomCatalogAction(this));
		myContextMenuActions.add(new RemoveCustomCatalogAction(this));
		myContextMenuActions.add(new BuyBasketBooksAction(this));
		myContextMenuActions.add(new ClearBasketAction(this));
	}

	private void fillListClickList() {
		myListClickActions.add(new OpenCatalogAction(this));
		myListClickActions.add(new OpenInBrowserAction(this));
		myListClickActions.add(new RunSearchAction(this, true));
		myListClickActions.add(new AddCustomCatalogAction(this));
		myListClickActions.add(new TopupAction(this));
		myListClickActions.add(new ShowBookInfoAction(this));
	}

	private List<? extends Action> getContextMenuActions(NetworkTree tree) {
		return tree instanceof NetworkBookTree ? NetworkBookActions
				.getContextMenuActions(this, (NetworkBookTree) tree, Connection)
				: myContextMenuActions;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View view,
			ContextMenu.ContextMenuInfo menuInfo) {
		if (myContextMenuActions.isEmpty()) {
			fillContextMenuList();
		}

		final int position = ((AdapterView.AdapterContextMenuInfo) menuInfo).position;
		final NetworkTree tree = (NetworkTree) getListAdapter().getItem(
				position);
		if (tree != null) {
			menu.setHeaderTitle(tree.getName());
			for (Action a : getContextMenuActions(tree)) {
				if (a.isVisible(tree) && a.isEnabled(tree)) {
					menu.add(0, a.Code, 0, a.getContextLabel(tree));
				}
			}
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		final int position = ((AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo()).position;
		final NetworkTree tree = (NetworkTree) getListAdapter().getItem(
				position);
		if (tree != null) {
			for (Action a : getContextMenuActions(tree)) {
				if (a.Code == item.getItemId()) {
					checkAndRun(a, tree);
					return true;
				}
			}
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public void onListItemClick(ListView listView, View view, int position,
			long rowId) {
		if (myListClickActions.isEmpty()) {
			fillListClickList();
		}

		final NetworkTree tree = (NetworkTree) getListAdapter().getItem(
				position);
		for (Action a : myListClickActions) {
			if (a.isVisible(tree) && a.isEnabled(tree)) {
				checkAndRun(a, tree);
				return;
			}
		}

		listView.showContextMenuForChild(view);
	}

	private final AuthenticationActivity.CredentialsCreator myCredentialsCreator = new AuthenticationActivity.CredentialsCreator(
			this, BASIC_AUTHENTICATION_CODE);

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent intent) {
		switch (requestCode) {
		case BASIC_AUTHENTICATION_CODE:
			myCredentialsCreator.onDataReceived(resultCode, intent);
			break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		if (myOptionsMenuActions.isEmpty()) {
			fillOptionsMenuList();
		}

		// final NetworkTree tree = (NetworkTree)getCurrentTree();
		for (Action a : myOptionsMenuActions) {
			final MenuItem item = menu.add(0, a.Code, Menu.NONE, "");
			if (a.IconId != -1) {
				item.setIcon(a.IconId);
			}
		}
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);

		final NetworkTree tree = (NetworkTree) getCurrentTree();
		for (Action a : myOptionsMenuActions) {
			final MenuItem item = menu.findItem(a.Code);
			if (a.isVisible(tree)) {
				item.setVisible(true);
				item.setEnabled(a.isEnabled(tree));
				item.setTitle(a.getOptionsLabel(tree));
			} else {
				item.setVisible(false);
			}
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		final NetworkTree tree = (NetworkTree) getCurrentTree();
		for (Action a : myOptionsMenuActions) {
			if (a.Code == item.getItemId()) {
				checkAndRun(a, tree);
				break;
			}
		}
		return true;
	}

	private void updateLoadingProgress() {
		final NetworkTree tree = (NetworkTree) getCurrentTree();
		final NetworkTree lTree = getLoadableNetworkTree(tree);
		final NetworkTree sTree = RunSearchAction.getSearchTree(tree);
		setProgressBarIndeterminateVisibility(NetworkLibrary.Instance()
				.isUpdateInProgress()
				|| NetworkLibrary.Instance().getStoredLoader(lTree) != null
				|| NetworkLibrary.Instance().getStoredLoader(sTree) != null);
	}

	// method from NetworkLibrary.ChangeListener
	public void onLibraryChanged(final NetworkLibrary.ChangeListener.Code code,
			final Object[] params) {
		runOnUiThread(new Runnable() {
			public void run() {
				switch (code) {
				default:
					updateLoadingProgress();
					getListAdapter().replaceAll(getCurrentTree().subTrees());
					getListView().invalidateViews();
					break;
				case InitializationFailed:
					showInitLibraryDialog((String) params[0]);
					break;
				case InitializationFinished:
					NetworkLibrary.Instance().runBackgroundUpdate(false);
					if (myDeferredIntent != null) {
						openTreeByIntent(myDeferredIntent);
						myDeferredIntent = null;
					}
					break;
				case Found:
					openTree((NetworkTree) params[0]);
					break;
				case NotFound:
					UIUtil.showErrorMessage(NetworkLibraryActivity.this,
							"emptyNetworkSearchResults");
					break;
				case EmptyCatalog:
					UIUtil.showErrorMessage(NetworkLibraryActivity.this,
							"emptyCatalog");
					break;
				case NetworkError:
					UIUtil.showMessageText(NetworkLibraryActivity.this,
							(String) params[0]);
					break;
				}
			}
		});
	}

	private static NetworkTree getLoadableNetworkTree(NetworkTree tree) {
		while (tree instanceof NetworkAuthorTree
				|| tree instanceof NetworkSeriesTree) {
			if (tree.Parent instanceof NetworkTree) {
				tree = (NetworkTree) tree.Parent;
			} else {
				return null;
			}
		}
		return tree;
	}

	@Override
	protected void onCurrentTreeChanged() {
		NetworkLibrary.Instance().fireModelChangedEvent(
				NetworkLibrary.ChangeListener.Code.SomeCode);
	}

	private void showInitLibraryDialog(String error) {
		final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				if (which == DialogInterface.BUTTON_POSITIVE) {
					Util.initLibrary(NetworkLibraryActivity.this);
				} else {
					finish();
				}
			}
		};

		final ZLResource dialogResource = ZLResource.resource("dialog");
		final ZLResource boxResource = dialogResource
				.getResource("networkError");
		final ZLResource buttonResource = dialogResource.getResource("button");
		new AlertDialog.Builder(this)
				.setTitle(boxResource.getResource("title").getValue())
				.setMessage(error)
				.setIcon(0)
				.setPositiveButton(
						buttonResource.getResource("tryAgain").getValue(),
						listener)
				.setNegativeButton(
						buttonResource.getResource("cancel").getValue(),
						listener)
				.setOnCancelListener(new DialogInterface.OnCancelListener() {
					public void onCancel(DialogInterface dialog) {
						listener.onClick(dialog,
								DialogInterface.BUTTON_NEGATIVE);
					}
				}).create().show();
	}

	private void checkAndRun(final Action action, final NetworkTree tree) {
		if (tree instanceof NetworkCatalogTree) {
			final NetworkCatalogTree catalogTree = (NetworkCatalogTree) tree;
			switch (catalogTree.getVisibility()) {
			case B3_FALSE:
				break;
			case B3_TRUE:
				action.run(tree);
				break;
			case B3_UNDEFINED:
				Util.runAuthenticationDialog(this, tree.getLink(),
						new Runnable() {
							public void run() {
								if (catalogTree.getVisibility() != ZLBoolean3.B3_TRUE) {
									return;
								}
								if (action.Code != ActionCode.SIGNIN) {
									action.run(tree);
								}
							}
						});
				break;
			}
		} else {
			action.run(tree);
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		/*
		 * case R.id.tabbarHome: // setListAdapter(new
		 * NetworkLibraryAdapter(this)); startActivity(new
		 * Intent(getApplicationContext(), NetworkLibraryActivity.class));
		 * 
		 * break; case R.id.tabbarCate:
		 * 
		 * // setListAdapter(new NetworkLibraryAdapter(this)); startActivity(new
		 * Intent(getApplicationContext(), NetworkLibraryActivity.class));
		 * 
		 * break; case R.id.tabbarTop: // setListAdapter(null);
		 * 
		 * startActivity(new Intent(getApplicationContext(),
		 * NetworkLibraryActivity.class)); break; case R.id.tabbarFov: //
		 * setListAdapter(null); startActivity(new
		 * Intent(getApplicationContext(), NetworkLibraryActivity.class));
		 * break; case R.id.tabbarSearch: // setListAdapter(null);
		 * startActivity(new Intent(getApplicationContext(),
		 * NetworkLibraryActivity.class)); break;
		 */
		default:
			break;
		}
	}

}
